#include <fstream>   // file I/O
#include <iostream>
#include <iomanip>   // format manipulation
#include <string>
#include <list>
#include <stdlib.h>
#include "matriz.h"

#define RUNTEST(t,d) { cerr << endl << "Corriendo test " << #t << ": " << #d << endl; t(); cerr << "Terminado test " << #t << " OK!" << endl << endl; }
#define dim 2
#define filas 4

using namespace std;

//void test0() {
//    // la copia de una matriz es independiente de otra.
//    Matriz m(filas,dim);
//    Matriz n(filas,dim);
//    n.setPos(0,0,2);
//    assert( n(0,0) != m(0,0) );
//    // el operador asignacion genera matrices independientes
//    Matriz o = n;
//    o.setPos(0,0,3);
//    assert( n(0,0) != o(0,0) );
//    // testeando memoria
//    Matriz *dinamica = new Matriz(10, 10);
//    delete dinamica;
//}
//
//void test1(){
//        Matriz m(filas,dim);
//        Matriz n(filas,dim);
//        Matriz res(filas,dim);
//        for(int i=0; i<filas; i++) {
//                for(int j=0;j<dim;j++) {
//                        double mij = rand()%11+1;
//                        double nij = rand()%11+1;
//                        m.setPos(i,j ,mij);
//                        n.setPos(i,j ,nij);
//                        res.setPos(i,j,mij+nij);
//                }
//        }
//        Matriz k = m+n;
//		//Matriz k = m.suma(n);
//        assert(res == k);
//}
//
//
//void test2(){
//        Matriz m(filas,dim);
//        Matriz n(filas,dim);
//        Matriz res(filas,dim);
//        for(int i=0;i<filas;i++) {
//                for(int j=0;j<dim;j++) {
//                        double mij = rand()%11+1;
//                        double nij = rand()%11+1;
//                        m.setPos(i, j, mij);
//                        n.setPos(i, j, nij);
//                        res.setPos(i, j, mij - nij);
//                }
//        }
//        Matriz k = m-n;
//        assert( res == k);
//}
//
//void test3(){
//        Matriz m(filas,dim);
//        Matriz res(filas,dim);
//        double num= rand()%7+1;
//        for(int i=0;i<filas;i++){
//                for(int j=0;j<dim;j++){
//                        double mij = rand()%11+1;
//                        m.setPos(i,j ,mij);
//                        res.setPos(i, j, num*mij);
//                }
//        }
//        Matriz k = num*m;
//        assert(res == k);
//}
//
//void test4(){
//        Matriz m(filas,dim);
//        Matriz n(dim,filas);
//        Matriz res(filas,filas);
//        for(int i=0;i<filas;i++) {
//                for(int j=0;j<dim;j++) {
//                        m.setPos(i,j ,rand()%11+1);
//                }
//        }
//		for(int i=0;i<dim;i++) {
//                for(int j=0;j<filas;j++) {
//                        n.setPos(i,j ,rand()%11+1);
//                }
//        }
//
//        for(unsigned int i = 0; i < m.n; i++){
//                for(unsigned int j = 0; j < n.m; j++){
//                        double temp = 0;
//                        for(unsigned int k = 0; k < n.n; k++){
//                                temp += m(i,k) * n(k,j);
//                        }
//                        res.setPos(i, j, temp);
//                }
//        }
//}
//
//void test5() {
//        Matriz m(filas,filas);
//        for(int i=0;i<filas;i++) {
//                for(int j=0;j<filas;j++) {
//                        m.setPos(i,j ,rand()%(23+j)+1);
//                }
//        }
//        cout << "MATRIZ M: " << endl;
//        cout << m;
//        double a[filas];
//        cout << "B es: [";
//        for(int x = 0; x < filas; x++){
//                if(x != 0)
//                        cout << ", ";
//                a[x] = rand()%17;
//                cout << a[x];
//        }
//        cout << "]"<<endl;
//        double b[filas];
//        if(m.resolver(a,b))
//                cout << "RESOLVIO!" << endl;
//        else
//                cout << "NO RESOLVIO :S"<< endl;
//}
//
void test6() {
    Matriz n(3,3);
	Matriz r(3,3);
	Matriz q(3,3);
	double alpha = 0.001;
	
	n.setPos(1,1,1);
	n.setPos(1,2,2);
	n.setPos(1,3,3);
	n.setPos(2,1,2);
	n.setPos(2,2,2);
	n.setPos(2,3,3);
	n.setPos(3,1,3);
	n.setPos(3,2,3);
	n.setPos(3,3,3);
	
	
	r=n;
	
	q.identidad();	
	
	int error = n.factQR(q,r,alpha);
	if (error ==0){
	cout<<r<<endl;
	cout<<q<<endl;
	Matriz a(3,3);
	a=q.producto(r);
	cout<<a<<endl;
	
	cout<<"A es diagonal?? "<<a.esDiagonal()<<endl;
	Matriz b(4,4);
	b.identidad();
	cout<<"Ahora B es diagonal?? "<<b.esDiagonal()<<endl;
	
	//Obtenemos los autovalores
	unsigned int k = a.n;
	Matriz autovec(k,1);
	autovec = a.getKAutovectores(a,k,0.001,0.01);
	

	}
}

int main(){
    //srand(time(NULL));
    //RUNTEST(test0, Probando Constructores y asignacion);
    //RUNTEST(test1, Probando la suma);
    //RUNTEST(test2, Probando la resta);
    //RUNTEST(test3, Probando multiplicacion escalar);
    //RUNTEST(test4, Probando multiplicacion con matriz);
    //RUNTEST(test5, Resolviendo ecuacion);
    RUNTEST(test6, Probando Factorizacion QR);
    
    return 0;
}


